#include "../include/myhead.h"
#include "../include/ser_pthread.h"
#include "../include/list_queue.h"
#include "../include/msg.h"
#include "../include/mysqlite.h"
#include "../include/pclient_pthread.h"
#include "../include/device_pthread.h"
#include "../include/myjson.h"

int get_client_cli_or_dev(list_t *clinode, msg_t *clientmsg);

/**
 * 任务线程，根据接收到的消息判断是PC客户端还是设备端
 */
void *client_routine(void *arg)
{
    int ret;
    int devcmd;
    msg_t clientmsg;

    INFO_LOG("tid = %ld\n", pthread_self());

    // 设置当前线程为分离态
    pthread_detach(pthread_self());
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);      // 可以被取消
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // 立即取消

    list_t *clinode = (list_t *)arg;

login:
    memset(clinode->name, 0, sizeof(clinode->name));
    memset(clinode->psword, 0, sizeof(clinode->psword));
    clinode->verify = 0;
    memset(&clientmsg, 0, sizeof(clientmsg));
    ret = get_client_cli_or_dev(clinode, &clientmsg);
    if (ret == 1) // PC客户端
    {
        // 首先处理第一条数据 判断是登录 注册
        if (pcclient_login_regist_manage(clinode, &clientmsg) == -1)
        {
            INFO_LOG("The username and password are incorrect. Please wait to log in again.");
            goto login;
        }

        // 成功登录，将设备添加到对应的PC客户端链表中
        strcpy(clinode->name, clientmsg.ID);
        strcpy(clinode->psword, clientmsg.PS);

        list_add_head(get_pcclient_list_head(), clinode);

        // 打印链表
        list_traverse(get_pcclient_list_head());

        // 开启接收数据处理函数 循环处理，退出 出错或结束
        pclient_msg_handle(clinode, &clientmsg);

        // 关闭文件描述符
        close(clinode->client_sockfd);

        // 从链表中删除对应节点数据
        list_del_node(get_pcclient_list_head(), clinode->client_sockfd);
    }
    else if (ret == 0) // 设备端
    {
        // 首先处理第一条数据 判断是登录是否正确
        if (device_login_manage(clinode, &clientmsg) == -1)
        {
            // 登录的用户名密码错误，或者设备号已经在链表中,不在需要等待下次登录，直接关闭套接字
            close(clinode->client_sockfd);
            free(clinode);
            goto close;
        }

        // 成功登录，将设备添加到对应的PC客户端链表中
        strcpy(clinode->devnum, clientmsg.device_id);
        list_add_head(get_device_list_head(), clinode);

        // 开启接收数据处理函数
        device_msg_handle(clinode, &clientmsg);

        // 关闭文件描述符
        close(clinode->client_sockfd);

        // 从链表中删除对应节点数据
        list_del_node(get_device_list_head(), clinode->client_sockfd);
    }
    else
    {
        ERR_PRIENT("error");
        return NULL;
    }

close:
    INFO_LOG("close pthread:%ld\n", pthread_self());
    return NULL;
}

/**
 * 判断连接的是PC客户端还是设备端
 *  0 pc客户端， 1 设备端
 */
int get_client_cli_or_dev(list_t *clinode, msg_t *clientmsg)
{
    int ret;

    // 获取用户名和密码,登录设备信息
    if ((ret = recv_json_to_struct(clinode, clientmsg)) == -1)
    {
        goto err;
    }

    // 已经正确接收到消息，返回设备标识符
    return clientmsg->msgtype;

err:
    close(clinode->client_sockfd);
    if (clinode != NULL)
        free(clinode);
    return -1;
}

